﻿using AutoUpdaterDotNET;
using System;
using System.Collections.Generic;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace DaHuaSnapShot
{
    //执行curl --digest -u 摄像头账号:密码 --location --request GET 'http://192.168.*.*/cgi-bin/snapshot.cgi?channel=1' -o 1.jpg
    public partial class Form1 : Form
    {
        private DataTable dtCamera = new DataTable();
        private DataTable dtCaptrue = new DataTable();
        private CancellationTokenSource _captureCts;
        private Task _captureTask;

        public Form1()
        {
            InitializeComponent();        

            dataGridView1.DataSource = dtCamera;
            dataGridView2.DataSource = dtCaptrue;
            dtCaptrue.Columns.Add("id", typeof(int));
            dtCaptrue.Columns.Add("ip", typeof(string));
            dtCaptrue.Columns.Add("username", typeof(string));
            dtCaptrue.Columns.Add("password", typeof(string));
            dtCaptrue.Columns.Add("savepath", typeof(string));
            dtCaptrue.Columns.Add("cameraname", typeof(string));
            dtCamera.Columns.Add("id", typeof(int));
            dtCamera.Columns.Add("ip", typeof(string));
            dtCamera.Columns.Add("username", typeof(string));
            dtCamera.Columns.Add("password", typeof(string));
            dtCamera.Columns.Add("savepath", typeof(string));
            dtCamera.Columns.Add("cameraname", typeof(string));
        }       
        private void button_gettest_Click(object sender, EventArgs e)
        {
            if (!string.IsNullOrWhiteSpace(textBox_ip.Text) && !string.IsNullOrEmpty(textBox_username.Text) && !string.IsNullOrEmpty(textBox_password.Text) && !string.IsNullOrEmpty(label4.Text))
            {
                string cameraUrl = $"http://{textBox_ip.Text}/cgi-bin/snapshot.cgi?channel=1"; 
                string username = textBox_username.Text; 
                string password = textBox_password.Text; 
                DateTime now = DateTime.Now;
                string fileName = now.ToString("yyyy-MM-dd-HH-mm-ss") + ".jpg";
                string savePath = Path.Combine(label4.Text, fileName);

                // 创建CameraSnapshot实例并获取快照
                CameraSnapshot camera = new CameraSnapshot();

                // 异步方式调用
                var success = camera.GetSnapshot(cameraUrl, username, password, savePath);
                if (success)
                {
                    pictureBox1.Image?.Dispose(); // 释放图像资源
                    pictureBox1.Image = null;
                    // 使用 FromStream 并确保释放文件锁
                    byte[] bytes = File.ReadAllBytes(savePath);
                    using (var ms = new MemoryStream(bytes))
                    {
                        pictureBox1.Image = Image.FromStream(ms);
                    }
                    MessageBox.Show("配置正确，可以获取抓图");
                    button_ToSql.Enabled = true;
                }
                else
                {
                    MessageBox.Show("无法完成请求，了解具体情况请查看日志！", "错误");
                }
            }
            else
            {
                MessageBox.Show("请完整填写以上信息！");
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            using (FolderBrowserDialog folderBrowserDialog = new FolderBrowserDialog())
            {
                if (folderBrowserDialog.ShowDialog() == DialogResult.OK)
                {
                    string filePath = folderBrowserDialog.SelectedPath; ; // 获取用户选择的文件路径
                    label4.Text = filePath;
                }
            }
        }

        private void button_ToSql_Click(object sender, EventArgs e)
        {
            using (var db = DBHelper.GetDb())
            {
                CameraData cd = new CameraData
                {
                    ip = textBox_ip.Text.Trim(),
                    username = textBox_username.Text.Trim(),
                    password = textBox_password.Text.Trim(),
                    savepath = label4.Text.Trim(),
                    cameraname=textBox_cameraname.Text.Trim(),
                };
                db.Insertable<CameraData>(cd).ExecuteCommand();
            }
            ShowData();
            FreshForm();
        }

        private void FreshForm()
        {
            textBox_ip.Text = "";
            textBox_username.Text = "";
            textBox_password.Text = "";
            textBox_cameraname.Text = "";
            label4.Text = "";
            button_ToSql.Enabled = false;
            pictureBox1.Image?.Dispose(); // 释放图像资源
            pictureBox1.Image = null;
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            // 安装AutoUpdater 1.5版即可满足自动更新功能,1.7增加了对core和.net5的支持
            // 修改AssemblyInfo.cs里的版本号，同时修改更新服务器里的xml文件中的版本号即可
            // 设置AutoUpdater的配置
            AutoUpdater.Start("http://192.168.2.188/AppUpdater/DaHuaSnapShot/Updates/AutoUpdaterStarter.xml");
            // 检查数据库文件是否存在,不存在则创建
            string dbPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "CameraConfig.sqlite");
            if (!File.Exists(dbPath))
            {
                // 创建数据库文件并初始化表结构
                using (var db = DBHelper.GetDb())
                {
                    // 根据CameraData模型创建表
                    db.CodeFirst.InitTables(typeof(CameraData));
                }
            }            
            FreshForm();
            ShowData();
        }

        private void ShowData()
        {
            dtCamera.Rows.Clear();
            using (var db = DBHelper.GetDb())
            {
                List<CameraData> list = db.Queryable<CameraData>().ToList();
                foreach (var item in list)
                {
                    DataRow dr = dtCamera.NewRow();
                    dr["id"] = item.Id;
                    dr["ip"] = item.ip;
                    dr["username"] = item.username;
                    dr["password"] = item.password;
                    dr["savepath"] = item.savepath;
                    dr["cameraname"] = item.cameraname;
                    dtCamera.Rows.Add(dr);
                }
            }
        }

        private async void button_CaptureOne_Click(object sender, EventArgs e)
        {
            if (dtCaptrue.Rows.Count > 0)
            {
                var tasks = new List<Task>();
                for (int i = 0; i < dtCaptrue.Rows.Count; i++)
                {
                    string ipstr = dtCaptrue.Rows[i]["ip"].ToString();
                    string username = dtCaptrue.Rows[i]["username"].ToString();
                    string password = dtCaptrue.Rows[i]["password"].ToString();
                    string path = dtCaptrue.Rows[i]["savepath"].ToString();
                    string cameraname = dtCaptrue.Rows[i]["cameraname"].ToString();
                    tasks.Add(ImageCapture(ipstr, username, password, path, cameraname));
                }
                try
                {
                    await Task.WhenAll(tasks);
                }
                catch (Exception ex)
                {
                    // 记录或提示错误，避免抛出到 UI 线程未处理
                    MessageBox.Show($"抓图过程中发生错误：{ex.Message}");
                }
            }
        }

        public async Task ImageCapture(string ipstr, string username, string password, string savepath,string cameraname)
        {
            string cameraUrl = $"http://{ipstr}/cgi-bin/snapshot.cgi?channel=1";
            DateTime now = DateTime.Now;
            string fileName = cameraname + now.ToString("yyyy-MM-dd-HH-mm-ss") + ".jpg";
            string savePath = Path.Combine(savepath, fileName);
            // 创建CameraSnapshot实例并获取快照
            CameraSnapshot camera = new CameraSnapshot();
            // 异步方式调用
            await camera.GetSnapshotAsync(cameraUrl, username, password, savePath);
        }

        private void button_TimedCapture_Click(object sender, EventArgs e)
        {
            int j = 1;
            if (button_TimedCapture.Text == "定时抓图")
            {
                if (!int.TryParse(textBox_Second.Text, out int result))
                {
                    MessageBox.Show("请输入有效的间隔秒数");
                    return;
                }
                if (dtCaptrue.Rows.Count == 0)
                {
                    MessageBox.Show("抓图列表为空");
                    return;
                }

                // 如果已有任务，先取消
                _captureCts?.Cancel();
                _captureCts = new CancellationTokenSource();
                var token = _captureCts.Token;

                _captureTask = Task.Run(async () =>
                {
                    try
                    {
                        while (!token.IsCancellationRequested)
                        {
                            var tasks = new List<Task>();
                            for (int i = 0; i < dtCaptrue.Rows.Count; i++)
                            {
                                string ipstr = dtCaptrue.Rows[i]["ip"].ToString();
                                string username = dtCaptrue.Rows[i]["username"].ToString();
                                string password = dtCaptrue.Rows[i]["password"].ToString();
                                string path = dtCaptrue.Rows[i]["savepath"].ToString();
                                string cameraname = dtCaptrue.Rows[i]["cameraname"].ToString();
                                tasks.Add(ImageCapture(ipstr, username, password, path, cameraname));
                            }
                            try
                            {
                                await Task.WhenAll(tasks);
                            }
                            catch
                            {
                                // 忽略单次抓图错误，继续下一次
                            }

                            this.Invoke(new Action(() =>
                            {
                                label_CaptrueInfo.Text = "已发送抓图请求" + j + "次";
                            }));
                            j++;

                            await Task.Delay(result * 1000, token);
                        }
                    }
                    catch (OperationCanceledException)
                    {
                        // 任务被取消，正常退出
                    }
                }, token);

                MessageBox.Show("定时抓图开始执行");
                // 更新按钮文本到执行状态
                button_TimedCapture.Text = "停止抓图";
            }
            else
            {
                // 请求停止
                _captureCts?.Cancel();
                _captureCts = null;
                button_TimedCapture.Text = "定时抓图";
                label_CaptrueInfo.Text = "";
                j = 1;
                MessageBox.Show("查看日志可了解任务执行情况！");
            }
        }

        private void dataGridView1_DoubleClick(object sender, EventArgs e)
        {
            CameraData cd = new CameraData
            {
                Id = Convert.ToInt32(dataGridView1.SelectedRows[0].Cells[0].Value),
                ip = dataGridView1.SelectedRows[0].Cells[1].Value.ToString(),
                username = dataGridView1.SelectedRows[0].Cells[2].Value.ToString(),
                password = dataGridView1.SelectedRows[0].Cells[3].Value.ToString(),
                savepath = dataGridView1.SelectedRows[0].Cells[4].Value.ToString(),
                cameraname = dataGridView1.SelectedRows[0].Cells[5].Value.ToString(),
            };
            if (dtCaptrue.Select("id=" + cd.Id.ToString()).Count() == 0)
            {
                DataRow dr = dtCaptrue.NewRow();
                dr["id"] = cd.Id;
                dr["ip"] = cd.ip;
                dr["username"] = cd.username;
                dr["password"] = cd.password;
                dr["savepath"] = cd.savepath;
                dr["cameraname"] = cd.cameraname;
                dtCaptrue.Rows.Add(dr);
                dataGridView1.SelectedRows[0].DefaultCellStyle.BackColor = Color.OrangeRed;
            }
            else
            {
                MessageBox.Show("抓图列表已包含此数据!");
            }
        }

        private void dataGridView2_DoubleClick(object sender, EventArgs e)
        {
            int id = Convert.ToInt32(dataGridView2.SelectedRows[0].Cells[0].Value);
            DataRow dr1 = dtCaptrue.Select("id=" + id).First();
            dtCaptrue.Rows.Remove(dr1);
            foreach (DataGridViewRow dr2 in dataGridView1.Rows)
            {
                if (int.TryParse(dr2.Cells["Column1"].Value.ToString(), out int ID))
                {
                    if (ID == id)
                    {
                        dr2.DefaultCellStyle.BackColor = Color.White;
                    }
                }
            }
        }

        private void textBox_ip_Leave(object sender, EventArgs e)
        {
            string ip=textBox_ip.Text;
            Regex regex = new Regex(@"^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$");

            if (!regex.IsMatch(ip))      
            {
                MessageBox.Show("IP地址不合法","错误");
                textBox_ip.Text = "";
                textBox_ip.Focus();
            }
        }

        private void dataGridView1_CellMouseClick(object sender, DataGridViewCellMouseEventArgs e)
        {
            if (e.Button == MouseButtons.Right)
            {
                if (e.RowIndex >= 0 && e.ColumnIndex >= 0)
                {
                    //若右键点击行未被选中，则清除其他选中行，并选中当前行
                    if (dataGridView1.Rows[e.RowIndex].Selected == false)
                    {
                        dataGridView1.ClearSelection();
                        dataGridView1.Rows[e.RowIndex].Selected = true;
                    }
                    //右键点击行已被选中
                    if (dataGridView1.SelectedRows.Count == 1)
                    {
                        dataGridView1.CurrentCell = dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex];
                    }

                    contextMenuStrip1.Show(MousePosition.X, MousePosition.Y);
                }
            }
        }

        private void 删除相机信息ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            int id = (int)dataGridView1.SelectedCells[0].Value;
            using(var db=DBHelper.GetDb())
            {
                if(db.Deleteable<CameraData>(new CameraData() { Id=id}).ExecuteCommand()>0)
                {
                    MessageBox.Show("删除成功！");
                    ShowData();
                }
            }
        }

        private void 清空相机信息ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            using (var db = DBHelper.GetDb())
            {
                string sql1= "DELETE FROM CameraData";
                string sql2 = "DELETE FROM sqlite_sequence WHERE name = 'CameraData'";
                if (db.Ado.ExecuteCommand(sql1) > 0 && db.Ado.ExecuteCommand(sql2) > 0)
                {
                    MessageBox.Show("相机信息数据已清空！");
                    ShowData();
                }
            }
        }
    }
}